package com.learn.spring.test;

import com.learn.spring.Book;
import com.learn.spring.Order;
import com.learn.spring.User;
import com.learn.spring.bean.CollectionModel;
import com.learn.spring.bean.Emp;
import com.learn.spring.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Case1 {

    @Test
    public void test1() throws InterruptedException {
        /**
         * 1、IOC 思想基于 IOC 容器完成，IOC 容器底层就是对象工厂
         *  注：容器是用来装东西的，bean容器，是存放对象的容器，对象可能以任何方式存放，比如xml，存放类型信息，工厂就可以是解析xml后还原出对象的东西；
         *  或者缓存对象，那么工厂则可以实现填充好缓存，或是来自于网络、串行化、json等等。spring中默认bean是来自xml和注解。当然工厂是接口可以由我们自行扩展
         * 2.Spring提供IOC容器实现两种方式:（两个接口）
         * (1) BeanFactory
         * IOC容器基础实现方式，属于spring内置的一般我们并不使用。
         * 非继承 ApplicationContext 的子类，加载配置文件时候不会创建对象，在获取对象（使用）才去创建对象
         *
         * (2) ApplicationContext
         *  实际上 ApplicationContext 接口继承自 BeanFactory
         *  主要实现类 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext
         *  它们在加载配置文件时候就会把在配置文件对象进行创建
         */

        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//        BeanFactory context = new ClassPathXmlApplicationContext("beans.xml");
//        BeanFactory context = new XmlBeanFactory(new ClassPathResource("beans.xml"));
        Thread.sleep(3000);
        context.getBean("user", User.class).show();
    }

    @Test
    public void test2() {
        /**
         * IOC 容器操作 bean 管理（基于 XML 方式）：
         * bean管理分为2块，1 创建对象 2 注入属性
         * 1. 基于 xml 方式创建对象
         *  配置 Bean 对象创建
         *  <bean id="user" class="com.learn.spring.User"></bean>
         *  (1) 在 spring 配置文件中，使用 bean 标签，标签里面添加对应属性，就可以实现对象创建
         *  (2) 在bean标签有很多属性,介绍常用的属性:
         *   * id 属性:唯一标识
         *   * class 属性:类全路径（包类路径),
         *  (3）创建对象时候，默认也是执行无参数构造方法完成对象创建·
         *
         * 2、基于xml方式注入属性
         *  (1) DI:依赖注入,就是注入属性
         *   * 第一种注入方式:使用set方法进行注入,
         *   * 第二种注入方式:使用有参数构造进行注入
         */

        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        System.out.println(context.getBean("book", Book.class));
        System.out.println(context.getBean("book1", Book.class));
    }

    @Test
    public void test3() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        System.out.println(context.getBean("order", Order.class));
        System.out.println(context.getBean("order1", Order.class));
    }

    @Test
    public void test4() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
        context.getBean("userService", UserService.class).add();
    }

    @Test
    public void test5() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
        System.out.println(context.getBean("emp1", Emp.class));
        System.out.println(context.getBean("emp2", Emp.class));
    }

    @Test
    public void test6() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
        System.out.println(context.getBean("collection", CollectionModel.class));
    }

    @Test
    public void test7() {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
        System.out.println(context.getBean("collection", CollectionModel.class));
    }

}
